/*
 * Copyright (c) Jiandong.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { ViewAtIndex } from './ViewAtIndex';
import { LayoutUpdateListener } from './UIImplementation';
import { ReactShadowNode } from './ReactShadowNode';
import { PixelUtil } from './PixelUtil';
import { ReadableArray } from '../bridge/ReadableArray';
import hilog from '@ohos.hilog';
import { ReactStylesDiffMap } from './ReactStylesDiffMap';
import { ThemedReactContext } from './ThemedReactContext';
import { View } from './View';
import { Runnable } from '../bridge/queue/MessageQueueThread';
import { ReactContext } from '../bridge/ReactContext';
import { Callback } from './Callback';
import ArrayList from '@ohos.util.ArrayList';
import Deque from '@ohos.util.Deque';
import Array from '@ohos.util.ArrayList';

import { NativeViewHierarchyManager } from './NativeViewHierarchyManager'


export interface DispatchCommandViewOperation {
  executeWithExceptions(): void

  incrementRetries(): void

  getRetries(): number
}

interface UIOperation {
  execute(): void;
}

abstract class ViewOperation implements UIOperation {
  protected mTag: number;
  protected mNativeViewHierarchyManager: NativeViewHierarchyManager

  public constructor(tag: number, nativeViewHierarchyManager: NativeViewHierarchyManager) {
    this.mTag = tag;
    this.mNativeViewHierarchyManager = nativeViewHierarchyManager
  }

  abstract execute(): void
}

export class UIViewOperationQueue {
  //    public static final int DEFAULT_MIN_TIME_LEFT_IN_FRAME_FOR_NONBATCHED_OPERATION_MS = 8;
  private static TAG = "UIViewOperationQueue";
  private mMeasureBuffer = new Array<number>();
  private mNativeViewHierarchyManager: NativeViewHierarchyManager;
  private mDispatchRunnablesLock = new Object();
  private mNonBatchedOperationsLock = new Object();
  //    private final UIViewOperationQueue.DispatchUIFrameCallback mDispatchUIFrameCallback;
  private mReactContext: ReactContext
  private mViewCommandOperations: ArrayList<DispatchCommandViewOperation> = new ArrayList();
  private mOperations: ArrayList<UIOperation> = new ArrayList();
  //    @GuardedBy("mDispatchRunnablesLock")
  private mDispatchUIRunnables: ArrayList<Runnable> = new ArrayList();
  //    @GuardedBy("mNonBatchedOperationsLock")
  private mNonBatchedOperations: Deque<UIOperation> = new Deque();
  //    private mViewHierarchyUpdateDebugListener?: NotThreadSafeViewHierarchyUpdateDebugListener;
  //    private boolean mIsDispatchUIFrameCallbackEnqueued = false;
  private mIsInIllegalUIState = false;
  private mIsProfilingNextBatch = false;
  //    private long mNonBatchedExecutionTotalTime;
  //    private long mProfiledBatchCommitStartTime;
  //    private long mProfiledBatchCommitEndTime;
  //    private long mProfiledBatchLayoutTime;
  //    private long mProfiledBatchDispatchViewUpdatesTime;
  //    private long mProfiledBatchRunStartTime;
  //    private long mProfiledBatchRunEndTime;
  //    private long mProfiledBatchBatchedExecutionTime;
  //    private long mProfiledBatchNonBatchedExecutionTime;
  //    private long mThreadCpuTime;
  private mCreateViewCount: number;
  private mUpdatePropertiesOperationCount: number;

  public constructor(reactContext: ReactContext, nativeViewHierarchyManager: NativeViewHierarchyManager, minTimeLeftInFrameForNonBatchedOperationMs: number) {
    this.mNativeViewHierarchyManager = nativeViewHierarchyManager;
    //        this.mDispatchUIFrameCallback = new UIViewOperationQueue.DispatchUIFrameCallback(reactContext, minTimeLeftInFrameForNonBatchedOperationMs == -1 ? 8 : minTimeLeftInFrameForNonBatchedOperationMs);
    this.mReactContext = reactContext;
  }

  public getNativeViewHierarchyManager(): NativeViewHierarchyManager {
    return this.mNativeViewHierarchyManager;
  }

  //    public void setViewHierarchyUpdateDebugListener(@Nullable NotThreadSafeViewHierarchyUpdateDebugListener listener) {
  //        this.mViewHierarchyUpdateDebugListener = listener;
  //    }
  //
  //    public void profileNextBatch() {
  //        this.mIsProfilingNextBatch = true;
  //        this.mProfiledBatchCommitStartTime = 0L;
  //        this.mCreateViewCount = 0L;
  //        this.mUpdatePropertiesOperationCount = 0L;
  //    }
  //
  //    public Map<String, Long> getProfiledBatchPerfCounters() {
  //        Map<String, Long> perfMap = new HashMap();
  //        perfMap.put("CommitStartTime", this.mProfiledBatchCommitStartTime);
  //        perfMap.put("CommitEndTime", this.mProfiledBatchCommitEndTime);
  //        perfMap.put("LayoutTime", this.mProfiledBatchLayoutTime);
  //        perfMap.put("DispatchViewUpdatesTime", this.mProfiledBatchDispatchViewUpdatesTime);
  //        perfMap.put("RunStartTime", this.mProfiledBatchRunStartTime);
  //        perfMap.put("RunEndTime", this.mProfiledBatchRunEndTime);
  //        perfMap.put("BatchedExecutionTime", this.mProfiledBatchBatchedExecutionTime);
  //        perfMap.put("NonBatchedExecutionTime", this.mProfiledBatchNonBatchedExecutionTime);
  //        perfMap.put("NativeModulesThreadCpuTime", this.mThreadCpuTime);
  //        perfMap.put("CreateViewCount", this.mCreateViewCount);
  //        perfMap.put("UpdatePropsCount", this.mUpdatePropertiesOperationCount);
  //        return perfMap;
  //    }

  public isEmpty(): boolean {
    return this.mOperations.isEmpty() && this.mViewCommandOperations.isEmpty();
  }

  public addRootView(tag: number, rootView: View) {
    this.mNativeViewHierarchyManager.addRootView(tag, rootView);
  }

  public enqueueRemoveRootView(rootViewTag: number): void {
    this.mOperations.add(new RemoveRootViewOperation(rootViewTag, this.mNativeViewHierarchyManager));
  }

  public enqueueCreateView(themedContext: ThemedReactContext, viewReactTag: number, viewClassName: string, initialProps?: ReactStylesDiffMap) {
    hilog.info(0x0000, UIViewOperationQueue.TAG, "enqueueCreateView %{public}d", 11);
    ++this.mCreateViewCount;
    this.mNonBatchedOperations.insertEnd(new CreateViewOperation(themedContext, viewReactTag, viewClassName, this.mNativeViewHierarchyManager, initialProps));
  }
  //
  //    public void enqueueSetJSResponder(int tag, int initialTag, boolean blockNativeResponder) {
  //        this.mOperations.add(new ChangeJSResponderOperation(tag, initialTag, false, blockNativeResponder));
  //    }
  //
  //    public void enqueueClearJSResponder() {
  //        this.mOperations.add(new ChangeJSResponderOperation(0, 0, true, false));
  //    }
  //
  //    /** @deprecated */
  //    @Deprecated
  //    public enqueueDispatchCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
  //        UIViewOperationQueue.DispatchCommandOperation command = new DispatchCommandOperation(reactTag, commandId, commandArgs);
  //        this.mViewCommandOperations.add(command);
  //    }
  //
  //    public enqueueDispatchCommand(int reactTag, String commandId, @Nullable ReadableArray commandArgs) {
  //        UIViewOperationQueue.DispatchStringCommandOperation command = new DispatchStringCommandOperation(reactTag, commandId, commandArgs);
  //        this.mViewCommandOperations.add(command);
  //    }
  //
  //    public enqueueUpdateExtraData(int reactTag, Object extraData) {
  //        this.mOperations.add(new UpdateViewExtraData(reactTag, extraData));
  //    }
  //
  //    public enqueueShowPopupMenu(int reactTag, ReadableArray items, Callback error, Callback success) {
  //        this.mOperations.add(new ShowPopupMenuOperation(reactTag, items, error, success));
  //    }
  //
  //    public enqueueDismissPopupMenu() {
  //        this.mOperations.add(new DismissPopupMenuOperation());
  //    }

  //
  public enqueueUpdateProperties(reactTag: number, className: string, props: ReactStylesDiffMap) {
    ++this.mUpdatePropertiesOperationCount;
    this.mOperations.add(new UpdatePropertiesOperation(reactTag, props, this.mNativeViewHierarchyManager));
  }

  //    public void enqueueUpdateInstanceHandle(int reactTag, long instanceHandle) {
  //        this.mOperations.add(new UIViewOperationQueue.UpdateInstanceHandleOperation(reactTag, instanceHandle));
  //    }

  protected enqueueUIOperation(operation: UIOperation): void {
    //        SoftAssertions.assertNotNull(operation);
    this.mOperations.add(operation);
  }

  //    public void enqueueOnLayoutEvent(int tag, int screenX, int screenY, int screenWidth, int screenHeight) {
  //        this.mOperations.add(new UIViewOperationQueue.EmitOnLayoutEventOperation(tag, screenX, screenY, screenWidth, screenHeight));
  //    }
  //
  public enqueueUpdateLayout(parentTag: number, reactTag: number, x: number, y: number, width: number, height: number) {
      this.mOperations.add(new UpdateLayoutOperation(parentTag, reactTag, x, y, width, height));
  }

  public  enqueueManageChildren(reactTag: number, indicesToRemove?: number[], viewsToAdd?: ViewAtIndex[] , tagsToDelete?: number[]) {
      this.mOperations.add(new ManageChildrenOperation(reactTag, indicesToRemove, viewsToAdd, tagsToDelete));
  }
  //
  public enqueueSetChildren(reactTag: number, childrenTags: ReadableArray) {
      this.mOperations.add(new SetChildrenOperation(reactTag, childrenTags));
  }
  //
  //    public void enqueueSetLayoutAnimationEnabled(boolean enabled) {
  //        this.mOperations.add(new UIViewOperationQueue.SetLayoutAnimationEnabledOperation(enabled));
  //    }
  //
  //    public void enqueueConfigureLayoutAnimation(ReadableMap config, Callback onAnimationComplete) {
  //        this.mOperations.add(new UIViewOperationQueue.ConfigureLayoutAnimationOperation(config, onAnimationComplete));
  //    }
  //
  public enqueueMeasure(reactTag: number, callback: Callback) {
      this.mOperations.add(new MeasureOperation(reactTag, callback));
  }

  public enqueueMeasureInWindow(reactTag: number, callback: Callback) {
      this.mOperations.add(new MeasureInWindowOperation(reactTag, callback));
  }
  //
  //    public void enqueueFindTargetForTouch(int reactTag, float targetX, float targetY, Callback callback) {
  //        this.mOperations.add(new UIViewOperationQueue.FindTargetForTouchOperation(reactTag, targetX, targetY, callback));
  //    }
  //
  //    public void enqueueSendAccessibilityEvent(int tag, int eventType) {
  //        this.mOperations.add(new UIViewOperationQueue.SendAccessibilityEvent(tag, eventType));
  //    }
  //
  public enqueueLayoutUpdateFinished(node: ReactShadowNode, listener: LayoutUpdateListener) {
      this.mOperations.add(new LayoutUpdateFinishedOperation(node, listener));
  }
  //
  //    public void enqueueUIBlock(UIBlock block) {
  //        this.mOperations.add(new UIViewOperationQueue.UIBlockOperation(block));
  //    }
  //
  //    public void prependUIBlock(UIBlock block) {
  //        this.mOperations.add(0, new UIViewOperationQueue.UIBlockOperation(block));
  //    }
  //
      public dispatchViewUpdates(batchId: number, commitStartTime: number, layoutTime: number): void {
  //        SystraceMessage.beginSection(0L, "UIViewOperationQueue.dispatchViewUpdates").arg("batchId", batchId).flush();
  //
  //        try {
  //            final long dispatchViewUpdatesTime = SystemClock.uptimeMillis();
  //            final long nativeModulesThreadCpuTime = SystemClock.currentThreadTimeMillis();
  //            final ArrayList viewCommandOperations;
  //            if (!this.mViewCommandOperations.isEmpty()) {
  //                viewCommandOperations = this.mViewCommandOperations;
  //                this.mViewCommandOperations = new ArrayList();
  //            } else {
  //                viewCommandOperations = null;
  //            }
  //
  //            final ArrayList batchedOperations;
  //            if (!this.mOperations.isEmpty()) {
  //                batchedOperations = this.mOperations;
  //                this.mOperations = new ArrayList();
  //            } else {
  //                batchedOperations = null;
  //            }
  //
  //            final ArrayDeque nonBatchedOperations;
  //            synchronized(this.mNonBatchedOperationsLock) {
  //                if (!this.mNonBatchedOperations.isEmpty()) {
  //                    nonBatchedOperations = this.mNonBatchedOperations;
  //                    this.mNonBatchedOperations = new ArrayDeque();
  //                } else {
  //                    nonBatchedOperations = null;
  //                }
  //            }
  //
  //            if (this.mViewHierarchyUpdateDebugListener != null) {
  //                this.mViewHierarchyUpdateDebugListener.onViewHierarchyUpdateEnqueued();
  //            }
  //
  //            Runnable runOperations = new Runnable() {
  //                public void run() {
  //                    SystraceMessage.beginSection(0L, "DispatchUI").arg("BatchId", batchId).flush();
  //
  //                    try {
  //                        long runStartTime = SystemClock.uptimeMillis();
  //                        Iterator var3;
  //                        if (viewCommandOperations != null) {
  //                            var3 = viewCommandOperations.iterator();
  //
  //                            while(var3.hasNext()) {
  //                                UIViewOperationQueue.DispatchCommandViewOperation op = (UIViewOperationQueue.DispatchCommandViewOperation)var3.next();
  //
  //                                try {
  //                                    op.executeWithExceptions();
  //                                } catch (RetryableMountingLayerException var11) {
  //                                    if (op.getRetries() == 0) {
  //                                        op.incrementRetries();
  //                                        UIViewOperationQueue.this.mViewCommandOperations.add(op);
  //                                    } else {
  //                                        ReactSoftExceptionLogger.logSoftException(UIViewOperationQueue.TAG, new ReactNoCrashSoftException(var11));
  //                                    }
  //                                } catch (Throwable var12) {
  //                                    ReactSoftExceptionLogger.logSoftException(UIViewOperationQueue.TAG, var12);
  //                                }
  //                            }
  //                        }
  //
  //                        UIViewOperationQueue.UIOperation opx;
  //                        if (nonBatchedOperations != null) {
  //                            var3 = nonBatchedOperations.iterator();
  //
  //                            while(var3.hasNext()) {
  //                                opx = (UIViewOperationQueue.UIOperation)var3.next();
  //                                opx.execute();
  //                            }
  //                        }
  //
  //                        if (batchedOperations != null) {
  //                            var3 = batchedOperations.iterator();
  //
  //                            while(var3.hasNext()) {
  //                                opx = (UIViewOperationQueue.UIOperation)var3.next();
  //                                opx.execute();
  //                            }
  //                        }
  //
  //                        if (UIViewOperationQueue.this.mIsProfilingNextBatch && UIViewOperationQueue.this.mProfiledBatchCommitStartTime == 0L) {
  //                            UIViewOperationQueue.this.mProfiledBatchCommitStartTime = commitStartTime;
  //                            UIViewOperationQueue.this.mProfiledBatchCommitEndTime = SystemClock.uptimeMillis();
  //                            UIViewOperationQueue.this.mProfiledBatchLayoutTime = layoutTime;
  //                            UIViewOperationQueue.this.mProfiledBatchDispatchViewUpdatesTime = dispatchViewUpdatesTime;
  //                            UIViewOperationQueue.this.mProfiledBatchRunStartTime = runStartTime;
  //                            UIViewOperationQueue.this.mProfiledBatchRunEndTime = UIViewOperationQueue.this.mProfiledBatchCommitEndTime;
  //                            UIViewOperationQueue.this.mThreadCpuTime = nativeModulesThreadCpuTime;
  //                            Systrace.beginAsyncSection(0L, "delayBeforeDispatchViewUpdates", 0, UIViewOperationQueue.this.mProfiledBatchCommitStartTime * 1000000L);
  //                            Systrace.endAsyncSection(0L, "delayBeforeDispatchViewUpdates", 0, UIViewOperationQueue.this.mProfiledBatchDispatchViewUpdatesTime * 1000000L);
  //                            Systrace.beginAsyncSection(0L, "delayBeforeBatchRunStart", 0, UIViewOperationQueue.this.mProfiledBatchDispatchViewUpdatesTime * 1000000L);
  //                            Systrace.endAsyncSection(0L, "delayBeforeBatchRunStart", 0, UIViewOperationQueue.this.mProfiledBatchRunStartTime * 1000000L);
  //                        }
  //
  //                        UIViewOperationQueue.this.mNativeViewHierarchyManager.clearLayoutAnimation();
  //                        if (UIViewOperationQueue.this.mViewHierarchyUpdateDebugListener != null) {
  //                            UIViewOperationQueue.this.mViewHierarchyUpdateDebugListener.onViewHierarchyUpdateFinished();
  //                        }
  //                    } catch (Exception var13) {
  //                        UIViewOperationQueue.this.mIsInIllegalUIState = true;
  //                        throw var13;
  //                    } finally {
  //                        Systrace.endSection(0L);
  //                    }
  //
  //                }
  //            };
  //            SystraceMessage.beginSection(0L, "acquiring mDispatchRunnablesLock").arg("batchId", batchId).flush();
  //            synchronized(this.mDispatchRunnablesLock) {
  //                Systrace.endSection(0L);
  //                this.mDispatchUIRunnables.add(runOperations);
  //            }
  //
  //            if (!this.mIsDispatchUIFrameCallbackEnqueued) {
  //                UiThreadUtil.runOnUiThread(new GuardedRunnable(this.mReactApplicationContext) {
  //                    public void runGuarded() {
  //                        UIViewOperationQueue.this.flushPendingBatches();
  //                    }
  //                });
  //            }
  //        } finally {
  //            Systrace.endSection(0L);
  //        }
  //
      }
  //
  //    void resumeFrameCallback() {
  //        this.mIsDispatchUIFrameCallbackEnqueued = true;
  //        ReactChoreographer.getInstance().postFrameCallback(CallbackType.DISPATCH_UI, this.mDispatchUIFrameCallback);
  //    }
  //
  //    void pauseFrameCallback() {
  //        this.mIsDispatchUIFrameCallbackEnqueued = false;
  //        ReactChoreographer.getInstance().removeFrameCallback(CallbackType.DISPATCH_UI, this.mDispatchUIFrameCallback);
  //        this.flushPendingBatches();
  //    }
  //
  //    private void flushPendingBatches() {
  //        if (this.mIsInIllegalUIState) {
  //            FLog.w("ReactNative", "Not flushing pending UI operations because of previously thrown Exception");
  //        } else {
  //            ArrayList runnables;
  //            synchronized(this.mDispatchRunnablesLock) {
  //                if (this.mDispatchUIRunnables.isEmpty()) {
  //                    return;
  //                }
  //
  //                runnables = this.mDispatchUIRunnables;
  //                this.mDispatchUIRunnables = new ArrayList();
  //            }
  //
  //            long batchedExecutionStartTime = SystemClock.uptimeMillis();
  //            Iterator var4 = runnables.iterator();
  //
  //            while(var4.hasNext()) {
  //                Runnable runnable = (Runnable)var4.next();
  //                runnable.run();
  //            }
  //
  //            if (this.mIsProfilingNextBatch) {
  //                this.mProfiledBatchBatchedExecutionTime = SystemClock.uptimeMillis() - batchedExecutionStartTime;
  //                this.mProfiledBatchNonBatchedExecutionTime = this.mNonBatchedExecutionTotalTime;
  //                this.mIsProfilingNextBatch = false;
  //                Systrace.beginAsyncSection(0L, "batchedExecutionTime", 0, batchedExecutionStartTime * 1000000L);
  //                Systrace.endAsyncSection(0L, "batchedExecutionTime", 0);
  //            }
  //
  //            this.mNonBatchedExecutionTotalTime = 0L;
  //        }
  //    }
}


//    private class DispatchUIFrameCallback extends GuardedFrameCallback {
//        private static final int FRAME_TIME_MS = 16;
//        private final int mMinTimeLeftInFrameForNonBatchedOperationMs;
//
//        private DispatchUIFrameCallback(ReactContext reactContext, int minTimeLeftInFrameForNonBatchedOperationMs) {
//            super(reactContext);
//            this.mMinTimeLeftInFrameForNonBatchedOperationMs = minTimeLeftInFrameForNonBatchedOperationMs;
//        }
//
//        public void doFrameGuarded(long frameTimeNanos) {
//            if (UIViewOperationQueue.this.mIsInIllegalUIState) {
//                FLog.w("ReactNative", "Not flushing pending UI operations because of previously thrown Exception");
//            } else {
//                Systrace.beginSection(0L, "dispatchNonBatchedUIOperations");
//
//                try {
//                    this.dispatchPendingNonBatchedOperations(frameTimeNanos);
//                } finally {
//                    Systrace.endSection(0L);
//                }
//
//                UIViewOperationQueue.this.flushPendingBatches();
//                ReactChoreographer.getInstance().postFrameCallback(CallbackType.DISPATCH_UI, this);
//            }
//        }
//
//        private void dispatchPendingNonBatchedOperations(long frameTimeNanos) {
//            while(true) {
//                UIViewOperationQueue.UIOperation nextOperation;
//                label30: {
//                    long timeLeftInFrame = 16L - (System.nanoTime() - frameTimeNanos) / 1000000L;
//                    if (timeLeftInFrame >= (long)this.mMinTimeLeftInFrameForNonBatchedOperationMs) {
//                        synchronized(UIViewOperationQueue.this.mNonBatchedOperationsLock) {
//                            if (!UIViewOperationQueue.this.mNonBatchedOperations.isEmpty()) {
//                                nextOperation = (UIViewOperationQueue.UIOperation)UIViewOperationQueue.this.mNonBatchedOperations.pollFirst();
//                                break label30;
//                            }
//                        }
//                    }
//
//                    return;
//                }
//
//                try {
//                    long nonBatchedExecutionStartTime = SystemClock.uptimeMillis();
//                    nextOperation.execute();
//                    UIViewOperationQueue.this.mNonBatchedExecutionTotalTime = SystemClock.uptimeMillis() - nonBatchedExecutionStartTime;
//                } catch (Exception var8) {
//                    UIViewOperationQueue.this.mIsInIllegalUIState = true;
//                    throw var8;
//                }
//            }
//        }
//    }

//    private final class SendAccessibilityEvent extends UIViewOperationQueue.ViewOperation {
//        private final int mEventType;
//
//        private SendAccessibilityEvent(int tag, int eventType) {
//            super(tag);
//            this.mEventType = eventType;
//        }
//
//        public void execute() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.sendAccessibilityEvent(this.mTag, this.mEventType);
//        }
//    }
//
//    private class UIBlockOperation implements UIViewOperationQueue.UIOperation {
//        private final UIBlock mBlock;
//
//        public UIBlockOperation(UIBlock block) {
//            this.mBlock = block;
//        }
//
//        public void execute() {
//            this.mBlock.execute(UIViewOperationQueue.this.mNativeViewHierarchyManager);
//        }
//    }
//
    export class LayoutUpdateFinishedOperation implements UIOperation {
        private readonly mNode: ReactShadowNode;
        private readonly mListener: LayoutUpdateListener;

        public constructor(node: ReactShadowNode, listener: LayoutUpdateListener) {
            this.mNode = node;
            this.mListener = listener;
        }

        public execute() {
            this.mListener.onLayoutUpdated(this.mNode);
        }
    }
//
//    private final class FindTargetForTouchOperation implements UIViewOperationQueue.UIOperation {
//        private final int mReactTag;
//        private final float mTargetX;
//        private final float mTargetY;
//        private final Callback mCallback;
//
//        private FindTargetForTouchOperation(int reactTag, float targetX, float targetY, Callback callback) {
//            this.mReactTag = reactTag;
//            this.mTargetX = targetX;
//            this.mTargetY = targetY;
//            this.mCallback = callback;
//        }
//
//        public void execute() {
//            try {
//                UIViewOperationQueue.this.mNativeViewHierarchyManager.measure(this.mReactTag, UIViewOperationQueue.this.mMeasureBuffer);
//            } catch (IllegalViewOperationException var9) {
//                this.mCallback.invoke(new Object[0]);
//                return;
//            }
//
//            float containerX = (float)UIViewOperationQueue.this.mMeasureBuffer[0];
//            float containerY = (float)UIViewOperationQueue.this.mMeasureBuffer[1];
//            int touchTargetReactTag = UIViewOperationQueue.this.mNativeViewHierarchyManager.findTargetTagForTouch(this.mReactTag, this.mTargetX, this.mTargetY);
//
//            try {
//                UIViewOperationQueue.this.mNativeViewHierarchyManager.measure(touchTargetReactTag, UIViewOperationQueue.this.mMeasureBuffer);
//            } catch (IllegalViewOperationException var8) {
//                this.mCallback.invoke(new Object[0]);
//                return;
//            }
//
//            float x = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[0] - containerX);
//            float y = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[1] - containerY);
//            float width = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[2]);
//            float height = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[3]);
//            this.mCallback.invoke(new Object[]{touchTargetReactTag, x, y, width, height});
//        }
//    }
//
    export class MeasureInWindowOperation implements UIOperation {
        private readonly mReactTag: number;
        private readonly mCallback: Callback;

        public constructor(reactTag: number, callback: Callback) {
            this.mReactTag = reactTag;
            this.mCallback = callback;
        }

        public execute() {
            try {
                //this.mNativeViewHierarchyManager.measureInWindow(this.mReactTag, UIViewOperationQueue.this.mMeasureBuffer);
            } catch (var5) {
                //this.mCallback(new Object[0]);
                this.mCallback()
                return;
            }

//            let x = PixelUtil.toDIPFromPixel(UIViewOperationQueue.this.mMeasureBuffer[0]);
//            let y = PixelUtil.toDIPFromPixel(UIViewOperationQueue.this.mMeasureBuffer[1]);
//            let width = PixelUtil.toDIPFromPixel(UIViewOperationQueue.this.mMeasureBuffer[2]);
//            let height = PixelUtil.toDIPFromPixel(UIViewOperationQueue.this.mMeasureBuffer[3]);
            // this.mCallback.invoke(new Object[]{x, y, width, height});
            this.mCallback();
        }
    }

    export class MeasureOperation implements UIOperation {
        private readonly mReactTag: number;
        private readonly mCallback: Callback;

        public constructor(reactTag: number, callback: Callback) {
            this.mReactTag = reactTag;
            this.mCallback = callback;
        }

        public execute() {
            try {
                //UIViewOperationQueue.this.mNativeViewHierarchyManager.measure(this.mReactTag, UIViewOperationQueue.this.mMeasureBuffer);
            } catch (var5) {
                this.mCallback();
                return;
            }

//            let x = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[0]);
//            let y = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[1]);
//            let width = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[2]);
//            let height = PixelUtil.toDIPFromPixel((float)UIViewOperationQueue.this.mMeasureBuffer[3]);
            // this.mCallback.invoke(new Object[]{0, 0, width, height, x, y});
        }
    }
//
//    private class ConfigureLayoutAnimationOperation implements UIViewOperationQueue.UIOperation {
//        private final ReadableMap mConfig;
//        private final Callback mAnimationComplete;
//
//        private ConfigureLayoutAnimationOperation(ReadableMap config, Callback animationComplete) {
//            this.mConfig = config;
//            this.mAnimationComplete = animationComplete;
//        }
//
//        public void execute() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.configureLayoutAnimation(this.mConfig, this.mAnimationComplete);
//        }
//    }
//
//    private class SetLayoutAnimationEnabledOperation implements UIViewOperationQueue.UIOperation {
//        private final boolean mEnabled;
//
//        private SetLayoutAnimationEnabledOperation(boolean enabled) {
//            this.mEnabled = enabled;
//        }
//
//        public void execute() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.setLayoutAnimationEnabled(this.mEnabled);
//        }
//    }
//
//    private abstract static class AnimationOperation implements UIViewOperationQueue.UIOperation {
//        protected final int mAnimationID;
//
//        public AnimationOperation(int animationID) {
//            this.mAnimationID = animationID;
//        }
//    }
//
//    private final class DismissPopupMenuOperation implements UIViewOperationQueue.UIOperation {
//        private DismissPopupMenuOperation() {
//        }
//
//        public void execute() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.dismissPopupMenu();
//        }
//    }
//
//    private final class ShowPopupMenuOperation extends UIViewOperationQueue.ViewOperation {
//        private final ReadableArray mItems;
//        private final Callback mError;
//        private final Callback mSuccess;
//
//        public ShowPopupMenuOperation(int tag, ReadableArray items, Callback error, Callback success) {
//            super(tag);
//            this.mItems = items;
//            this.mError = error;
//            this.mSuccess = success;
//        }
//
//        public void execute() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.showPopupMenu(this.mTag, this.mItems, this.mSuccess, this.mError);
//        }
//    }
//
//    private final class DispatchStringCommandOperation extends UIViewOperationQueue.ViewOperation implements UIViewOperationQueue.DispatchCommandViewOperation {
//        private final String mCommand;
//        @Nullable
//        private final ReadableArray mArgs;
//        private int numRetries = 0;
//
//        public DispatchStringCommandOperation(int tag, String command, @Nullable ReadableArray args) {
//            super(tag);
//            this.mCommand = command;
//            this.mArgs = args;
//        }
//
//        public void execute() {
//            try {
//                UIViewOperationQueue.this.mNativeViewHierarchyManager.dispatchCommand(this.mTag, this.mCommand, this.mArgs);
//            } catch (Throwable var2) {
//                ReactSoftExceptionLogger.logSoftException(UIViewOperationQueue.TAG, new RuntimeException("Error dispatching View Command", var2));
//            }
//
//        }
//
//        @UiThread
//        public void executeWithExceptions() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.dispatchCommand(this.mTag, this.mCommand, this.mArgs);
//        }
//
//        @UiThread
//        public void incrementRetries() {
//            ++this.numRetries;
//        }
//
//        public int getRetries() {
//            return this.numRetries;
//        }
//    }
//
//    /** @deprecated */
//    @Deprecated
//    private final class DispatchCommandOperation extends UIViewOperationQueue.ViewOperation implements UIViewOperationQueue.DispatchCommandViewOperation {
//        private final int mCommand;
//        @Nullable
//        private final ReadableArray mArgs;
//        private int numRetries = 0;
//
//        public DispatchCommandOperation(int tag, int command, @Nullable ReadableArray args) {
//            super(tag);
//            this.mCommand = command;
//            this.mArgs = args;
//        }
//
//        public void execute() {
//            try {
//                UIViewOperationQueue.this.mNativeViewHierarchyManager.dispatchCommand(this.mTag, this.mCommand, this.mArgs);
//            } catch (Throwable var2) {
//                ReactSoftExceptionLogger.logSoftException(UIViewOperationQueue.TAG, new RuntimeException("Error dispatching View Command", var2));
//            }
//
//        }
//
//        public void executeWithExceptions() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.dispatchCommand(this.mTag, this.mCommand, this.mArgs);
//        }
//
//        @UiThread
//        public void incrementRetries() {
//            ++this.numRetries;
//        }
//
//        @UiThread
//        public int getRetries() {
//            return this.numRetries;
//        }
//    }
//
//    private interface DispatchCommandViewOperation {
//        void executeWithExceptions();
//
//        void incrementRetries();
//
//        int getRetries();
//    }
//
//    private final class ChangeJSResponderOperation extends UIViewOperationQueue.ViewOperation {
//        private final int mInitialTag;
//        private final boolean mBlockNativeResponder;
//        private final boolean mClearResponder;
//
//        public ChangeJSResponderOperation(int tag, int initialTag, boolean clearResponder, boolean blockNativeResponder) {
//            super(tag);
//            this.mInitialTag = initialTag;
//            this.mClearResponder = clearResponder;
//            this.mBlockNativeResponder = blockNativeResponder;
//        }
//
//        public void execute() {
//            if (!this.mClearResponder) {
//                UIViewOperationQueue.this.mNativeViewHierarchyManager.setJSResponder(this.mTag, this.mInitialTag, this.mBlockNativeResponder);
//            } else {
//                UIViewOperationQueue.this.mNativeViewHierarchyManager.clearJSResponder();
//            }
//
//        }
//    }
//
//    private final class UpdateViewExtraData extends UIViewOperationQueue.ViewOperation {
//        private final Object mExtraData;
//
//        public UpdateViewExtraData(int tag, Object extraData) {
//            super(tag);
//            this.mExtraData = extraData;
//        }
//
//        public void execute() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.updateViewExtraData(this.mTag, this.mExtraData);
//        }
//    }
//
export class SetChildrenOperation extends ViewOperation {
    private readonly mChildrenTags: ReadableArray;

    public constructor(tag:number, childrenTags: ReadableArray) {
        super(tag, null);
        this.mChildrenTags = childrenTags;
    }

    public execute() {
        this.mNativeViewHierarchyManager.setChildren(this.mTag, this.mChildrenTags);
    }
}
//
export class ManageChildrenOperation extends ViewOperation {

    private readonly mIndicesToRemove?: number[];
    private readonly mViewsToAdd?: ViewAtIndex[];
    private readonly mTagsToDelete?: number[];

    public constructor(tag: number, indicesToRemove?: number[], viewsToAdd?: ViewAtIndex[], tagsToDelete?: number[]) {
        super(tag, null);
        this.mIndicesToRemove = indicesToRemove;
        this.mViewsToAdd = viewsToAdd;
        this.mTagsToDelete = tagsToDelete;
    }

    public execute() {
        this.mNativeViewHierarchyManager.manageChildren(this.mTag, this.mIndicesToRemove, this.mViewsToAdd, this.mTagsToDelete);
    }
}

export class CreateViewOperation extends ViewOperation {
  private static TAG = "react CreateViewOperation"
  private mThemedContext: ThemedReactContext;
  private mClassName: string;
  private mInitialProps: ReactStylesDiffMap;

  public constructor(themedContext: ThemedReactContext, tag: number, className: string, nativeViewHierarchyManager: NativeViewHierarchyManager, initialProps?: ReactStylesDiffMap) {
    super(tag, nativeViewHierarchyManager);
    this.mThemedContext = themedContext;
    this.mClassName = className;
    this.mInitialProps = initialProps;
    hilog.info(0x0000, CreateViewOperation.TAG, "constructor %{public}d", 11);

  }

  public execute() {
    this.mNativeViewHierarchyManager.createView(this.mThemedContext, this.mTag, this.mClassName, this.mInitialProps);
  }
}

export class UpdateLayoutOperation extends ViewOperation {
    private readonly mParentTag: number;
    private readonly mX: number;
    private readonly mY: number;
    private readonly mWidth: number;
    private readonly mHeight: number;

    public constructor(parentTag: number, tag: number, x: number, y: number, width: number, height: number) {
        super(tag, null);
        this.mParentTag = parentTag;
        this.mX = x;
        this.mY = y;
        this.mWidth = width;
        this.mHeight = height;
    }

    public execute() {
        this.mNativeViewHierarchyManager.updateLayout(this.mParentTag, this.mTag, this.mX, this.mY, this.mWidth, this.mHeight);
    }
}
//
//    private final class UpdateInstanceHandleOperation extends UIViewOperationQueue.ViewOperation {
//        private final long mInstanceHandle;
//
//        private UpdateInstanceHandleOperation(int tag, long instanceHandle) {
//            super(tag);
//            this.mInstanceHandle = instanceHandle;
//        }
//
//        public void execute() {
//            UIViewOperationQueue.this.mNativeViewHierarchyManager.updateInstanceHandle(this.mTag, this.mInstanceHandle);
//        }
//    }
//
//    private final class EmitOnLayoutEventOperation extends UIViewOperationQueue.ViewOperation {
//        private final int mScreenX;
//        private final int mScreenY;
//        private final int mScreenWidth;
//        private final int mScreenHeight;
//
//        public EmitOnLayoutEventOperation(int tag, int screenX, int screenY, int screenWidth, int screenHeight) {
//            super(tag);
//            this.mScreenX = screenX;
//            this.mScreenY = screenY;
//            this.mScreenWidth = screenWidth;
//            this.mScreenHeight = screenHeight;
//        }
//
//        public void execute() {
//            UIManagerModule uiManager = (UIManagerModule)UIViewOperationQueue.this.mReactApplicationContext.getNativeModule(UIManagerModule.class);
//            if (uiManager != null) {
//                uiManager.getEventDispatcher().dispatchEvent(OnLayoutEvent.obtain(-1, this.mTag, this.mScreenX, this.mScreenY, this.mScreenWidth, this.mScreenHeight));
//            }
//
//        }
//    }
//

class UpdatePropertiesOperation extends ViewOperation {
  private mProps: ReactStylesDiffMap;

  public constructor(tag: number, props: ReactStylesDiffMap, mHierarchyManager: NativeViewHierarchyManager) {
    super(tag, mHierarchyManager);
    this.mProps = props
  }

  public execute() {
    this.mNativeViewHierarchyManager.updateProperties(this.mTag, this.mProps);
  }
}

class RemoveRootViewOperation extends ViewOperation {
  public constructor(tag: number, hierarchyManager: NativeViewHierarchyManager) {
    super(tag, hierarchyManager);
  }

  public execute() {
    this.mNativeViewHierarchyManager.removeRootView(this.mTag);
  }
}
